#include <QDebug>
#include "myApplication.h"

MyApplication::MyApplication(int argc, char *argv[])
    :QApplication(argc,argv)
{
}

MyApplication::~MyApplication()
{

}

bool MyApplication::winEventFilter(MSG *msg,long *result)
{
    int msgType = msg->message;
    QString USBDisk;

    if(msgType == WM_DEVICECHANGE)
    {
        PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam;
        switch(msg->wParam)
        {
        case DBT_DEVICETYPESPECIFIC:
            {
                qDebug() << "DBT_DEVICETYPESPECIFIC " ;
                break;
            }
        case DBT_DEVICEARRIVAL:
            if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
            {
                PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
                if (lpdbv -> dbcv_flags == 0)
                {
                    USBDisk = QString(this->FirstDriveFromMask(lpdbv ->dbcv_unitmask));
                    qDebug() << "USB_Arrived and The USBDisk is: "<<USBDisk ;
                    USBDisk.append(":");
                   // if((diskList.isEmpty()) || (!diskList.contains("D")))
                    {
                        getDiskInfo(USBDisk);
                    }

                }
            }
            break;
        case DBT_DEVICEREMOVECOMPLETE:
            if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
            {
                PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
                if (lpdbv -> dbcv_flags == 0)
                {
                    USBDisk = QString(this->FirstDriveFromMask(lpdbv ->dbcv_unitmask));
                    USBDisk.append(":");
                    emit usbDiskRemoved(QVariant(USBDisk));
                }
            }
            break;
        }
    }
    return QApplication::winEventFilter(msg,result);
}

char MyApplication::FirstDriveFromMask (ULONG unitmask)
{
    char i;

    for (i = 0; i < 26; ++i)
    {
        if (unitmask & 0x1)
            break;
        unitmask = unitmask >> 1;
    }
    return (i + 'A');
}

void MyApplication::getDiskInfo(QString disk)
{

    QString myLabel;
    QString myVolume;
    QString myFileSystem;

    myLabel = getDiskName(disk);
    qDebug() << "wqj label:" + myLabel;
    // Get usb device's volume
    myVolume = getDiskVolume(disk);
    myFileSystem = getDiskFileSystem(disk);

    emit usbDiskInserted(QVariant(disk), QVariant(myLabel), QVariant(myVolume), QVariant(myFileSystem));
}

QString MyApplication::getDiskVolume(QString disk)
{
    TCHAR * devPath = (TCHAR *)QString2TCHAR(disk);
    TCHAR chBuf[256] = {0};
    ULARGE_INTEGER nFreeBytesAvailable;
    ULARGE_INTEGER nTotalNumberOfBytes;
    ULARGE_INTEGER nTotalNumberOfFreeBytes;
    QString totalVolume;
    float tmp;

    if (GetDiskFreeSpaceEx(devPath,
                           &nFreeBytesAvailable,
                           &nTotalNumberOfBytes,
                           &nTotalNumberOfFreeBytes))

    {
        wsprintf(chBuf, L"%I64d", nTotalNumberOfBytes.QuadPart);
        totalVolume = TCHAR2QString(chBuf);
        tmp = totalVolume.toFloat() / 1024 / 1024 / 1024;


        return QString::number(tmp, 'f', 1).append('G');
    }
}

QString MyApplication::getDiskName(QString disk)
{
    TCHAR* devPath = (TCHAR *)QString2TCHAR(disk);
    TCHAR chBuf[256] = {0};
    QString diskLabel;

    GetVolumeInformation(devPath,chBuf,256,NULL,NULL,NULL,NULL,10);

    diskLabel = TCHAR2QString(chBuf);
    return diskLabel;
}

QString MyApplication::getDiskFileSystem(QString disk)
{
    TCHAR* devPath = (TCHAR *)QString2TCHAR(disk);
    TCHAR chBuf[256] = {0};
    QString fileSystemType;

    GetVolumeInformation(devPath,NULL,0,NULL,NULL,NULL,chBuf,256);

    fileSystemType = TCHAR2QString(chBuf);
    return fileSystemType;
}

void MyApplication::getInsertedUSBDevices()
{
    TCHAR pszWordTable[] = {'A','B','C','D','E','F','G','H',
                              'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W',
                              'X','Y','Z'};
    DWORD dwDisk;
    DWORD dwBase = 0x1;
    DWORD dwCount = 0;          // ??????
    DWORD dwScanCount = 0;      // ??????????,????
    DWORD dwStyle;

    TCHAR szDiskPath[4] = {0};                  // ??????????

    dwDisk = GetLogicalDrives();

    while (dwDisk && dwCount < 26)
    {

        memset(szDiskPath, 0, sizeof(szDiskPath));

        if (dwDisk & dwBase)
        {
            qDebug() << "Size1;" << dwDisk;
            ::lstrcpyn(szDiskPath, pszWordTable + dwCount, 2);
            ::lstrcat(szDiskPath, TEXT("://"));
            dwStyle = GetDriveType(szDiskPath);

            // ??????
            if (DRIVE_REMOVABLE == dwStyle)
            {
                QString myDisk;
                QChar tmp;

                tmp = QChar((ushort)(pszWordTable[dwCount]));
                myDisk = QString("%1:").arg(tmp);
                qDebug() << "wqj:" << myDisk;
                getDiskInfo(myDisk);
                dwScanCount++;
            }
        }

        dwDisk = dwDisk & ~dwBase;
        dwDisk = dwDisk >> 1;
        dwCount++;
    }

}

